package com.framework.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.framework.core.common.enums.StatusEnum;
import com.framework.core.exception.CustomException;
import com.framework.system.entity.SysPost;
import com.framework.system.entity.SysUserPost;
import com.framework.system.entity.dto.SysPostAddDTO;
import com.framework.system.entity.dto.SysPostQueryDTO;
import com.framework.system.entity.dto.SysPostUpdateDTO;
import com.framework.system.entity.vo.SysPostListVO;
import com.framework.system.entity.vo.SysPostVO;
import com.framework.system.mapper.SysPostMapper;
import com.framework.system.mapper.SysUserPostMapper;
import com.framework.system.service.ISysPostService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 岗位表 服务实现类
 * </p>
 *
 * @author Kevin
 * @since 2021-06-22
 */
@Service
@AllArgsConstructor
public class SysPostServiceImpl implements ISysPostService {

    private SysPostMapper sysPostMapper;

    private SysUserPostMapper sysUserPostMapper;

    @Override
    public Page<SysPostListVO> selectSysPostWithPage(Page reqPage, SysPostQueryDTO req) {
        LambdaQueryWrapper<SysPost> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StrUtil.isNotBlank(req.getPostCode()), SysPost::getPostCode, req.getPostCode());
        queryWrapper.like(StrUtil.isNotBlank(req.getPostName()), SysPost::getPostName, req.getPostName());
        queryWrapper.orderByAsc(SysPost::getSort);
        Page<SysPost> page = sysPostMapper.selectPage(reqPage, queryWrapper);
        Page<SysPostListVO> voPage = BeanUtil.copyProperties(page, Page.class);
        voPage.setRecords(BeanUtil.copyToList(page.getRecords(), SysPostListVO.class));
        return voPage;
    }

    @Override
    public List<SysPostListVO> selectSysPostWithList(SysPostQueryDTO req) {
        LambdaQueryWrapper<SysPost> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StrUtil.isNotBlank(req.getPostCode()), SysPost::getPostCode, req.getPostCode());
        queryWrapper.like(StrUtil.isNotBlank(req.getPostName()), SysPost::getPostName, req.getPostName());
        queryWrapper.orderByAsc(SysPost::getSort);
        List<SysPost> list = sysPostMapper.selectList(queryWrapper);
        return BeanUtil.copyToList(list, SysPostListVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSysPost(SysPostAddDTO req) {
        if (!this.checkUniquePostName(req.getPostName(), null)) {
            throw new CustomException("岗位名称已存在");
        }
        if (!this.checkUniquePostCode(req.getPostCode(), null)) {
            throw new CustomException("岗位编码已存在");
        }
        SysPost entity = BeanUtil.copyProperties(req, SysPost.class);
        sysPostMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSysPost(SysPostUpdateDTO req) {
        if (!this.checkUniquePostName(req.getPostName(), req.getId())) {
            throw new CustomException("岗位名称已存在");
        }
        if (!this.checkUniquePostCode(req.getPostCode(), req.getId())) {
            throw new CustomException("岗位编码已存在");
        }
        SysPost entity = BeanUtil.copyProperties(req, SysPost.class);
        sysPostMapper.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeSysPost(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        idList.forEach(item -> {
            SysPost sysPost = sysPostMapper.selectById(item);
            SysUserPost sysUserPost = sysUserPostMapper.selectOne(Wrappers.lambdaQuery(SysUserPost.class).eq(SysUserPost::getPostId, item));
            if (Objects.nonNull(sysUserPost)) {
                throw new CustomException(String.format("岗位【%s】已被使用，无法删除", sysPost.getPostName()));
            }
        });
        idList.forEach(item -> {
            sysPostMapper.deleteById(item);
        });
    }

    @Override
    public SysPostVO getSysPost(String id) {
        SysPost entity = sysPostMapper.selectById(id);
        return BeanUtil.copyProperties(entity, SysPostVO.class);
    }

    @Override
    public List<SysPostVO> selectSysPostWithOption() {
        List<SysPost> sysPostList = sysPostMapper.selectList(Wrappers.lambdaQuery(SysPost.class)
                .eq(SysPost::getStatus, StatusEnum.YES.getCode())
                .orderByAsc(SysPost::getSort));
        return BeanUtil.copyToList(sysPostList, SysPostVO.class);
    }

    private Boolean checkUniquePostCode(String value, Long id) {
        if (StrUtil.isBlank(value)) {
            return true;
        }
        id = Objects.isNull(id) ? -1L : id;
        SysPost entity = sysPostMapper.selectOne(Wrappers.lambdaQuery(SysPost.class).eq(SysPost::getPostCode, value));
        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
    }

    private Boolean checkUniquePostName(String value, Long id) {
        if (StrUtil.isBlank(value)) {
            return true;
        }
        id = Objects.isNull(id) ? -1L : id;
        SysPost entity = sysPostMapper.selectOne(Wrappers.lambdaQuery(SysPost.class).eq(SysPost::getPostName, value));
        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
    }

}
